<?php

namespace Modules\Update\Entities;

use Modules\Core\Entities\BaseEntity as Model;

use Modules\Asset\Entities\AssetRecord;
use Modules\User\Entities\User;
use Modules\Box\Entities\Box;
use Modules\Product\Entities\Product;
use Modules\Agent\Entities\InviteRecord;

use Modules\Core\Entities\Device;

use Illuminate\Database\Schema\Blueprint;
use Jialeo\LaravelSchemaExtend\Schema;

use Modules\Activity\Entities\ActivitySku;

use Modules\Asset\Entities\Resale;
use Modules\Asset\Entities\Package;
use Modules\Asset\Entities\PackageSku;
use Modules\Order\Entities\OrderSku;

use Modules\Stats\Entities\UserStats;

use Modules\UI\Entities\Danmu;

use \Modules\Box\Entities\BoxSku;

// use Modules\Activity\Entities\YiFanShang\Sku ;

use Setting;
use DB;

// 收货地址
class UpdateCli
{
    protected $guarded = [];
    protected $table = 'addresses';

    static public $resourceName = '地址';

    protected $tool = NULL;

    public function update($tool)
    {
        $this->tool = $tool;
        $this->update7();
        $this->update10();
        $this->update11();
        $this->update20();
        $this->update23();
        $this->update23_1();
        $this->update25();
        $this->update36();
        $this->update47();
        $this->update48();
        $this->update53();
        $this->update54();
        $this->update55();

        $this->update56();

        $this->update57();

        $this->update59();

        $this->update60();

        $this->update61();
        $this->update63();
        $this->update93();
        $this->update95();
        $this->update98();
        $this->update99();
        $this->update100();
        $this->update101();
        $this->update102();

        $this->update103();
    } 

    public function update7() 
    {
        if (Setting::get('update7'))
            return true;

        // 补充所有积分记录中的user_id
        $list = AssetRecord::with('asset')->get();

        foreach ($list as $item) {
            $item->update([
                'user_id' => $item->asset->target_id
            ]);
        }

        Setting::set('update7', 1);
        return true;
    }

    public function update10() 
    {
        if (Setting::get('update10'))
            return true;

        $this->tool->call('module:migrate-refresh', [
            'module' => 'Activity'
        ]);
        // $this->tool->call('module:migrate', [
        //     'module' => 'Activity'
        // ]);

        Setting::set('update10', 1);
        return true;
    }

    public function update11() 
    {
        if (Setting::get('update11'))
            return true;

        foreach (Box::get() as $box) {
            $box->sales = $box->skus()->sum('sales');
            $box->save();
        }


        Setting::set('update11', 1);
        return true;
    }


    public function update20() 
    {
        if (Setting::get('update20'))
            return true;

        $list = ActivitySku::get(); 

        foreach ($list as $item) {
            $item->update([
                'per_session_stock' => $item->stock
            ]);
        }

        Setting::set('update20', 1);
        return true;
    }

    public function update23() 
    {
        if (Setting::get('update23'))
            return true;

        $list = Box::get(); 

        foreach ($list as $box) {
            $box->updateSalesAndStock();
            // $item->update([
            //     'per_session_stock' => $item->stock
            // ]);
        }

        Setting::set('update23', 1);
        return true;
    }

    public function update23_1() 
    {
        if (Setting::get('update23_1'))
            return true;

        $list = Product::get(); 

        foreach ($list as $item) {

            $page = @$item->ext->page;

            if ($page && is_array($page)) {
                foreach ($page['modules'] as $key => $module) {
                    if ($module['type'] === 'richtext') {
                        $module['type'] = 'html';
                        $module['html'] = $module['content'];
                        unset($module['content']);
                    }

                    $page['modules'][$key] = $module;
                }
            }

            $item->ext->update([
                'page' => $page
            ]);

        }

        Setting::set('update23_1', 1);

        return true;
    }

    public function update25() 
    {
        if (Setting::get('update25'))
            return true;

        $device = Device::create([
            'platform_type' => 'wechat',
            'platform_sub_type' => '',
            'client_type' => 'miniapp',
        ]);

        User::where('id', '>', 0)->update([
            'device_id' => $device->id
        ]);


        Setting::set('update25', 1);

        return true;
    }

    public function update36()
    {
        if (Setting::get('update36_2'))
            return true;

        // 更新所有
        $list = User::with('inviter.inviter.inviter')->get();

        foreach ($list as $user) {
            $indirct = null;

            $inviter = $user;
            $inviterIndex = 0;

            while ($inviter && $inviter->inviter) {

                if ($inviterIndex > 0) {
                    $indirct = $inviter;
                } 

                $inviter = $inviter->inviter;
                $inviterIndex ++;
            }

            $user->update([
                'root_inviter_id' => $inviter->id,
                'inviter_index' => $inviterIndex,
                'indirect_inviter_id' => $indirct ? $indirct->id : NULL,
                'invite_base_reward' => [
                    'score' => $user->invite_score ?: 0,
                    'redpack' => $user->invite_redpack ?: $user->invite_money,
                    'level_score' => $user->invite_level_score ?: 0
                ]
            ]);
        }


        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['invite_score', 'invite_money', 'invite_level_score']);
        });


        Setting::set('update36_2', 1);

        return true;
    }

    public function update47()
    {
        if (Setting::get('update47_3'))
            return true;

        $user = User::where('invite_reward_status', 0)->orderBy('id', 'asc')->get();

        foreach ($user as $user) {

            if ($user->inviter) {
                InviteRecord::create([
                    'direct_inviter_id' => $user->inviter->id,
                    'indirect_inviter_id' => $user->inviter->inviter_id,
                    'user_id' => $user->id,
                    'base_reward' => $user->base_reward,
                    'added_reward' => $user->added_reard,
                    'invite_index' => $user->inviter->invitees()->where('id', '<=', $user->id)->count(),
                    'invite_at' => $user->created_at,
                ]);

                $user->update([
                    'invite_reward_status'  => 1
                ]);
            }
            else {
                $user->update([
                    'invite_reward_status' => 2
                ]);
            }

            $user->update([
                'invite_total' => $user->invitees()->count()
            ]);
        }

        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['openid', 'invite_poster', 'client_type', 'client_sub_type', 'device_info', 'invite_added_reward', 'invite_base_reward']);
        });

        Setting::set('update47_3', 1);

        return true;
    }

    public function update48()
    {
        if (Setting::get('update48'))
            return true;


        $packageList = Package::where('id', '>', 0)->get();
        foreach ($packageList as $item) {
            $node = $item->node;

            if ($node) {
                $item->update([
                    'node_money_price' => $node->money_price,
                    'node_score_price' => $node->score_price
                ]);
            }
        }

        $packageSkuList = PackageSku::where('id', '>', 0)->get();
        foreach ($packageSkuList as $item) {
            $node = $item->node;

            if ($node) {
                $item->update([
                    'node_title' => $node->title,
                    'node_money_price' => $node->money_price,
                    'node_score_price' => $node->score_price
                ]);
            }
        }


        Setting::set('update48', 1);

        return true;
    }

    public function update53()
    {
        // if (Setting::get('update54'))
        //     return true;

        // // 更新用户邀请人数
        // $list = InviteRecord::get();
        // foreach ($list as  $item) {
        //     $item->direct_inviter->updateInviteeCount();

        //     // 清算结算佣金
        //     $item->direct_inviter->updateMyBrokerage();
        // }

        // // 更新sku的支付id和编号
        // $list = PackageSku::whereNotNull('pick_order_id')->with(['pick_order', 'pay_order'])->get();
        // foreach ($list as $item) {
        //     if ($item->pick_order) {
        //         $item->pick_order->sku->update([
        //             'pay_order_number' => $item->pay_order->number,
        //             'pay_order_id' => $item->pay_order->id
        //         ]);
        //     }
        // }

        // Setting::set('update54', 1);

        return true;
    }

    public function update54()
    {
        // if (Setting::get('update54-2'))
        //     return true;

        // // 更新用户邀请人数
        // $list = OrderSku::where('base_sku_type', 'product_sku')->get();

        // foreach ($list as $item) {
        //     if ($item->base_sku) {
        //         $node = $item->base_sku->getNodeEntity();
        //         $item->order->update([
        //             'supplier' => $node->supplier
        //         ]);

        //         $item->update([
        //             'supplier' => $node->supplier
        //         ]);
        //     }
        // }

        // Setting::set('update54-2', 1);

        return true;
    }


    public function update55()
    {
        if (Setting::get('update55'))
            return true;

        $list = PackageSku::where('source_type', 2)->get();

        foreach ($list as $item) {
            $resaleId = $item->pay_order->options['resale_id'];

            $resale = Resale::where('id', $resaleId)->first();

            $item->update([
                'from_package_sku_id' =>  $resale->package_sku_id
            ]);
        }

        Setting::set('update55', 1);

        return true;
    }

    public function update56()
    {
        if (Setting::get('update56'))
            return true;

        \Log::error('start 56');

        $list = PackageSku::where('node_type', 'yifanshang')->whereNull('open_index')->get();

        foreach ($list as $item) {
            $item->update([
                'is_special_sku' => 1
            ]);
        }

        Setting::set('update56', 1);

        \Log::error('complete 56');

        return true;
    }

    public function update57()
    {
        if (Setting::get('update58'))
            return true;

        \Log::error('start 58');
        $skus = \Modules\Activity\Entities\YiFanShang\Sku::whereHas('activity')->get();

        foreach ($skus as $sku) {
            $sku->stock = $sku->activity->room_total * $sku->total_per_room - $sku->sales;
            $sku->save();
        }

        Setting::set('update58', 1);
        \Log::error('complete 58');

        return true;
    }

    public function update59()
    {
        if (Setting::get('update59'))
            return true;

        $list = \Modules\Activity\Entities\YiFanShang\Activity::where('id', '>', 0)->get();

        foreach ($list as $item) {
            $item->updateStock();
        }

        Setting::set('update59', 1);

        return true;
    }

    public function update60()
    {
        if (Setting::get('update60_4'))
            return true;

        $list  = \Modules\Activity\Entities\ActivityOrder::status('pay_pending')->get();

        foreach ($list as $item) {
            $item->closeByPayTimeout();
            \Log::error('close');
        }


        $list = \Modules\Activity\Entities\YiFanShang\Room::whereHas('activity')->get();

        foreach ($list as $item) {

            $a = $item->calcAvailableStock();
            $sales = $item->activity->total_per_room - $a;

            $item->update([
                'sales' => $sales,
                'stock' => $a
            ]);

        }

        $list = \Modules\Activity\Entities\YiFanShang\Activity::where('id', '>', 0)->get();

        foreach ($list as $item) {
            $item->updateStock();
        }

        Setting::set('update60_4', 1);

        return true;
    }


    public function update61()
    {
        if (Setting::get('update62'))
            return true;

        $list  = [
            [
                'level' => 1,
                'is_preset' => 1,
                'title' => '初级分销员',
                'description' => '用户注册后默认归类为此级别分销员'
            ],
            [
                'level' => 2,
                'is_preset' => 1,
                'title' => '高级分销员',
                'description' => '可设置为更高佣金率'
            ],
            [
                'level' => 3,
                'is_preset' => 1,
                'title' => 'VIP分销员',
                'description' => '分销等级为1且开通VIP后升级为此等级分销员'
            ],
            [
                'level' => 4,
                'is_preset' => 1,
                'title' => '团队长',
                'description' => '团队长可统计其无限级下属的销售额度进行佣金计算'
            ],
        ];

        foreach ($list as $item) {
           \Modules\Agent\Entities\AgentLevel::create($item);
        }

        Setting::set('update62', 1);

        return true;
    }

    public function update63()
    {
        if (Setting::get('update63_1'))
            return true;

        $level = \Modules\Agent\Entities\AgentLevel::where('level', 1)->first();

        if ($level) {
            $level->update([
                'brokerage_setting' => Setting::get('agent_brokerage') ?: []
            ]);
        }

        Setting::set('update63_1', 1);

        return true;
    }

    public function update93()
    {
        if (Setting::get('update93'))
            return true;

        Setting::set('sys_box_depot', [
            'is_show_price' => 1
        ]);

        Setting::set('update93', 1);

        return true;
    }

    public function update95()
    {
        if (Setting::get('update96'))
            return true;

        $users = User::where('id', '>', 0)->get();

        foreach ($users as $user) {
            $user->generateInviteCode();
        }

        Setting::set('update96', 1);

        return true;
    }

    public function update98()
    {
        if (Setting::get('update98'))
            return true;

        $list = PackageSku::take(1000)->get();

        foreach ($list as $item) {
            Danmu::createWith($item);
        }

        // $users = User::where('id', '>', 0)->get();

        // foreach ($users as $user) {
        //     $user->generateInviteCode();
        // }

        Setting::set('update98', 1);

        return true;
    }

    public function update99()
    {
        if (Setting::get('update99'))
            return true;

        BoxSku::where('type', 0)->update([
            'level' => 1
        ]);

        BoxSku::where('type', 1)->update([
            'level' => 0
        ]);


        Setting::set('update99', 1);

        return true;
    }

    public function update100()
    {
        if (Setting::get('update100'))
            return true;

        $list = UserStats::get();

        foreach ($list as $item) {
            $item->update([
                'all_pay_money_price' => $item->box_pay_money_price + $item->yfs_pay_money_price + $item->fudai_pay_money_price,
                'all_pay_score_price' => $item->box_pay_score_price + $item->yfs_pay_score_price + $item->fudai_pay_score_price,
                'all_get_money_price' => $item->box_get_money_price + $item->yfs_get_money_price + $item->fudai_get_money_price,
                'all_get_score_price' => $item->box_get_score_price + $item->yfs_get_score_price + $item->fudai_get_score_price,
            ]);
        }

        Setting::set('update100', 1);

        return true;
    }

    public function update101()
    {
        if (Setting::get('update101_1'))
            return true;

        $list = UserStats::get();

        // 删除所有deleted_at的项 （从此不使用软删除）
        $tables = array_map('reset', \DB::select('SHOW TABLES'));
        foreach ($tables as $table) {
            \Log::error($table);
            if (Schema::hasColumn($table, 'deleted_at')) {
                DB::table($table)->whereNotNull('deleted_at')->delete();
            }
        }

        Schema::table('package_skus', function (Blueprint $table) {
            $table->integer('user_id')->index()->change();
            $table->integer('pay_order_id')->index()->change();
        }); 

        Setting::set('update101_1', 1);

        return true;
    }

    public function update102()
    {
        if (Setting::get('update102'))
            return true;

        Schema::table('yfs_rooms', function (Blueprint $table) {
            $table->integer('num')->index()->change();

            $table->integer('stock')->index()->change();
            $table->integer('sales')->index()->change();
            $table->integer('open_index')->index()->change();

        }); 

        Setting::set('update102', 1);

        return true;
    }

    public function update103()
    {
        if (Setting::get('update103'))
            return true;

        Schema::table('asset_records', function (Blueprint $table) {
            $table->char('asset_type', 15)->index();
        }); 

        Setting::set('update103', 1);

        return true;
    }
}
